const {
  validateCreateUser,
  validateUserLogin,
} = require("../utils/validate/user_validate");
const HttpException = require("../exceptions/http_expetion");
const User = require("../models/user");
const { md5Password, matchPassword } = require("../utils/md5");
const { sign } = require("../utils/jwt");

// 注册用户
module.exports.createUser = async (req, res, next) => {
  try {
    let { username, password, email } = req.body.user;

    // 数据校验
    let { error, validate } = validateCreateUser(username, password, email);
    if (!validate) {
      throw new HttpException(402, "用户提交验证数据失败！！！", error);
    }

    //业务验证
    //验证email是否存在
    const exisUser = await User.findByPk(email);
    if (exisUser) {
      throw new HttpException(402, "用户邮箱已存在！！！", "email 存在");
    }

    //创建用户
    //密码加密
    const md5PWD = await md5Password(password);
    //User model 存储数据库
    const user = await User.create({
      username,
      password: md5PWD,
      email,
    });

    //创建成功
    if (user) {
      //创建token
      let data = {};
      data.username = username;
      data.email = email;
      data.token = await sign(username, email);
      data.bio = null;
      data.avatar = null;
      //返回数据
      res.status(201).json({
        status: 1,
        message: "创建用户成功",
        data
      });
    }
    //整体异常捕获
  } catch (error) {
    next(error);
  }
};

//登录用户
module.exports.login = async (req, res, next) => {
  try {
    //获取请求数据
    let { email, password } = req.body.user;

    //验证请求数据
    let { error, validate } = validateUserLogin(email, password);

    //验证业务逻辑
    //用户是否存在
    const user = await User.findByPk(email);
    if (!user) {
      throw new HttpException(401, "用户不存在", "user not found!!!");
    }
    //密码是否匹配
    const oldMd5Pwd = user.dataValues.password;
    const match = await matchPassword(oldMd5Pwd, password);
    if (!match) {
      throw new HttpException(401, "用户密码错误", "password not match!!!");
    }

    //返回数据
    //生成token
    delete user.dataValues.password;
    user.dataValues.token = await sign(
      user.dataValues.username,
      user.dataValues.email
    );
    //返回数据
    return res.status(200).json({
      status: 1,
      message: "用户登录成功",
      data: user.dataValues
    });
  } catch (err) {
    next(err);
  }
};

//获取用户
module.exports.getUser = async (req, res) => {
  try {
    //获取请求数据
    const { email } = req.user;
    //验证email 是否存在
    const user = await User.findByPk(email);
    if (!user) {
      throw new HttpException(401, "邮箱不存在", "email not found");
    }
    //返回数据
    //去除password 字段
    delete user.dataValues.password;
    //添加token
    user.dataValues.token = req.token;
    //返回用户数据
    return res.status(200).json({
      status: 1,
      message: "获取用户信息成功",
      data: user.dataValues,
    });
  } catch (error) {
    next(error);
  }
};

//修改用户信息
module.exports.updateUser = async (req, res, next) => {
  try {
    //获取用户信息
    const { email } = req.user;
    //验证用户是否存在
    const user = await User.findByPk(email);
    if (!user) {
      throw new HttpException(401, "用户不存在", "user not found!!!");
    }
    //修改数据
    const bodyUser = req.body.user;
    if (bodyUser) {
      //数据字段判断是否修改
      const username = bodyUser.username ? bodyUser.username : user.username;
      const bio = bodyUser.bio ? bodyUser.bio : user.bio;
      const avatar = bodyUser.avatar ? bodyUser.avatar : user.avatar;
      //password 加密
      let password = user.password;
      if (bodyUser.password) {
        password = await md5Password(bodyUser.password);
      }
      //更新操作
      const updateUser = await user.update({ username, bio, avatar, password });
      //返回数据
      //去除password
      delete updateUser.dataValues.password;
      //添加token
      updateUser.dataValues.token = await sign(username, email);
      //返回数据
      return res.status(200).json({
        status: 1,
        message: "修改用户信息成功！！！",
        data: updateUser.dataValues,
      });
    } else {
      throw new HttpException(401, "更新数据为空", "update is null!!!");
    }
  } catch (error) {
    next(error);
  }
};
